import { HookTypeScriptHints, UiFrameworkExtension } from '../../components'
import { Link } from '@brillout/docpress'

Environment: server.

The `onRenderHtml()` hook defines how pages are rendered to HTML.

The `onRenderHtml()` and <Link href="/onRenderClient">`onRenderClient()`</Link> hooks are essentially the glue code between Vike and the UI framework (React/Vue/Solid/...).

> If you use a <UiFrameworkExtension />, then you don't need to define `onRenderHtml()` as it's already defined by <UiFrameworkExtension name noLink />.

```js
// +onRenderHtml.js
// Environment: server

import { escapeInject, dangerouslySkipEscape } from 'vike/server'
import { renderToHtml, createElement } from 'some-ui-framework'

export { onRenderHtml }

async function onRenderHtml(pageContext){
  const { Page, data } = pageContext
  const pageHtml = await renderToHtml(createElement(Page, data))

  const documentHtml = escapeInject`<!DOCTYPE html>
    <html>
      <head>
        <title>My SSR App</title>
      </head>
      <body>
        <div id="page-root">${dangerouslySkipEscape(pageHtml)}</div>
      </body>
    </html>`

  return {
    documentHtml,
    pageContext: {
      // We can define pageContext values here
    }
  }
}
```

Where `pageContext.Page` is the `Page` value of the page that is being rendered, see <Link href="/Page" />.


## TypeScript

```ts
// /**/+onRenderHtml.ts (usually /renderer/+onRenderHtml.ts)
// Environment: server

export { onRenderHtml }

import type { OnRenderHtmlAsync } from 'vike/types'
import { escapeInject, dangerouslySkipEscape } from 'vike/server'
import { renderToHtml, createElement } from 'some-ui-framework'

const onRenderHtml: OnRenderHtmlAsync = async (pageContext): ReturnType<OnRenderHtmlAsync> => {
  // ...
}
```

<HookTypeScriptHints hookTypeName="OnRenderHtmlAsync" />


## See also

 - <Link href="/onAfterRenderHtml" />
 - <Link href="/onRenderClient" />
 - <Link href="/Page" />
 - <Link href="/pageContext" />
